/*Copyright (C) 2009 - 2011 MASSART GAUTHIER and Careil Baptiste

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "../headers.h"
#include <SDL/SDL.h>
#include <SDL/SDL_mixer.h>
#define MAX_M3U_PATH_LENGHT 256
#define CANNAUX 8
#define FREQ 22050
#define CHUNCKSIZE 1024

/*variable global pour la gestion du thread*/
thread_son_vars glb_threadData;
CSLP_THREAD glb_threadId;

/*prototype de la fonction thread*/
void thread_gest_son(void *data);
void GestSons_PlayNextMusic(Container *playList, int *indexCurMusic, Mix_Music **curMusic, bool play_rand);
void GestSons_ParsePlayList(Container *playList);
int GestSons_Load(Container *sounds_list);
int Gestmusics_Load(Container *playList);
void GestSons_play_music(File **music, Container internPlayList, Mix_Music *curMusic);
void GestSons_jouer_son(File **son, Container sounds_list);

/*permet d'initialiser le gestionnaire de son*/
bool init_gest_sons() {
	bool retVal = true;
	glb_threadData.son = EMPTY_QUEUE;
	glb_threadData.music = EMPTY_QUEUE;
	glb_threadData.loop = false;
	glb_threadData.quitter = false;
	glb_threadData.running = false;
	glb_threadData.stop = false;
	glb_threadData.next = false;
	glb_threadData.shuffle = false;
	glb_threadData.is_music_paused = false;

	/* int DLL_IMPEXP CSLP_CreateThread(CSLP_THREAD* thread, void* func, void* arg);*/
	if(CSLP_CreateThread(&glb_threadId, thread_gest_son, &glb_threadData)) {
		Log(LOG_DEFAULT, "Impossible de lancer le thread de gestion du son.");
		retVal = false;
	}

	return retVal;
}

/*permet de jouer un son*/
bool jouer_son(Sons soundToPlay) {
	bool retVal = false;

	if(glb_threadData.running) {
		if(File_Push(& (glb_threadData.son), (int)(soundToPlay)) == 0) {
			retVal = true;
		}
	}
	return retVal;
}

/*permet de jouer une musique*/
bool play_music(musics musicsToPlay) {
	bool retVal = false;

	if(glb_threadData.running) {
		if(File_Push(& (glb_threadData.music), (int)(musicsToPlay)) == 0) {
			retVal = true;
			CSLP_Sleep(30);
		}
	}

	return retVal;
}

/*permet de mettre en pause ou non la musique*/
bool pause_music(bool toPause) {
	bool retVal = false;

	if(glb_threadData.running) {
		glb_threadData.is_music_paused = toPause;
		retVal = true;
	}

	return retVal;
}

/*permet de savoir si la musique est en pause ou non*/
bool is_music_paused() {
	return glb_threadData.is_music_paused;
}

/* Permet de jouer en boucle la musique en cours de lecture
*/
void music_loop(bool is_looping) {
	glb_threadData.loop = is_looping;
}

/* Permet de savoir si la musique est jouée en boucle ou non.
*/
bool is_music_looping() {
	return glb_threadData.loop;
}

/* Permet d'arrêter ou de reprendre la musique
*/
void stop_music(bool stoped) {
	glb_threadData.stop = stoped;
}

/* Permet de savoir si la musique a été arrétée
*/
bool is_music_stoped() {
	return glb_threadData.stop;
}

/* Permet d'arrêter la musique en train d'être jouée
** pour passer à la suivante. Si la musique est arréter,
** elle est remise en lecture. Ce n'est pas le cas si
** elle est en pause.
*/
void next_music() {
	if(is_music_stoped() == true) {
		stop_music(false);
	}
	else {
		glb_threadData.next = true;
	}
}

/* Permet de changer de mode de lecture entre aléatoire
** et continu.
*/
void music_set_mode_shuffle(bool shuffle) {
	glb_threadData.shuffle = shuffle;
}

/* Permet de connaitre le mode de lecture courant.
*/
bool music_get_mode_shuffle() {
	return glb_threadData.shuffle;
}

/*permet de fermer le gestionnaire de son*/
void close_gest_sons() {
	glb_threadData.quitter = true;
	CSLP_WaitThread(glb_threadId);
}

/*fonction utilisée par le thread
**permet de lire la prochaine musique de la liste de lecture passée en argument
**retourne le canal utilisé pour la lecture de la musique
*/
void GestSons_PlayNextMusic(Container *playList, int *indexCurMusic, Mix_Music **curMusic, bool play_rand) {
	int play_return = -1;
	int i;
	/*libération de la musique précédemment chargée*/

	if(*curMusic != NULL) {
		Mix_FreeMusic(*curMusic);
		*curMusic = NULL;
	}

	if(play_rand == true) {
		do {
			i = random(0, Container_Size(*playList));
		}
		while(i == *indexCurMusic && Container_Size(*playList) > 1);
	}
	else {
		i = *indexCurMusic + 1;
	}

	/*boucle de recherche de musique jouable*/
	while(Container_Size(*playList) > 0 && play_return == -1) {
		if(i >= Container_Size(*playList)) {
			i = 0;
		}

		/*chargement de la musique*/
		*curMusic = Mix_LoadMUS((char *)(Container_Get(*playList, i)));

		if(*curMusic == NULL) {	/*erreur de chargement*/
			Log(LOG_SDL_mixer, "Impossible de charger la musique suivante :");
			Log(LOG_SDL_mixer, (char *)(Container_Get(*playList, i)));
			free(Container_Get(*playList, i));
			Container_Delete(playList, i);
			i--;
		}
		else {	/*lecture de la musique*/
			play_return = Mix_FadeInMusic(*curMusic, 1, 500);

			if(play_return == -1) {	/*erreur de lecture*/
				Log(LOG_SDL_mixer, "La lecture de la musique suivante a échouée :");
				Log(LOG_SDL_mixer, (char *)(Container_Get(*playList, i)));
				Log(LOG_SDL_mixer, Mix_GetError());
				/*libération de la musique*/
				Mix_FreeMusic(*curMusic);
				*curMusic = NULL;
				free(Container_Get(*playList, i));
				Container_Delete(playList, i);
				i--;
			}
			else {	/*modification de l'index de la musique courante*/
				*indexCurMusic = i;
			}
		}

		i++;
	}

	if(play_return == -1) {
		*indexCurMusic = play_return;
	}
}

/*fonction utilisée par le thread
**permet de parser une liste de lecture et de renvoyer la liste des fichiers
**dans un tableau
*/
void GestSons_ParsePlayList(Container *playList) {
	char emptyLine[MAX_M3U_PATH_LENGHT];
	char *newLine = NULL;
	int newLineLenght;
	char *nameFile = "playList.m3u";
	FILE *playListFile = NULL;

	/*ouverture du fichier*/
	playListFile = fopen(nameFile, "r");

	if(playListFile == NULL) {
		Log(LOG_DEFAULT, "GestSons_ParsePlayList : Impossible d'ouvrir le fichier de la liste de lecture :");
		Log(LOG_DEFAULT, nameFile);
		return;
	}

	/*parsage du fichier (m3u)*/
	while(fgets(emptyLine, MAX_M3U_PATH_LENGHT, playListFile) != NULL) {
		if(emptyLine[0] != '#'
				&& emptyLine[0] != '\n'
				&& emptyLine[0] != '\b'
				&& emptyLine[0] != '\r') {
			newLineLenght = strlen(emptyLine);

			if(newLineLenght >= MAX_M3U_PATH_LENGHT - 1) {
				Log(LOG_DEFAULT, "GestSons_ParsePlayList : Une chaine de plus de 255 caractères a été lue dans le fichier de la liste de lecture. Elle sera ignorée.");

				while(strchr(emptyLine, '\n') == NULL) {
					if(fgets(emptyLine, MAX_M3U_PATH_LENGHT, playListFile) == NULL) {
						break;
					}
				}
			}
			else {
				/*supression du retour chariot*/
				remove_ret_line(emptyLine);

				/*actualisation de la longueur de la chaine*/
				newLineLenght = strlen(emptyLine);

				/*ajout de la chaine à la liste*/
				newLine = malloc(newLineLenght * sizeof(char) + 1);

				strcpy(newLine, emptyLine);

				Container_PushBack(playList, newLine);
			}
		}
	} /*fin du parsage du fichier mu3*/

	fclose(playListFile);
}

/*fonction utilisé par le thread
**permet de charger les sons. Ils sont stockés par SDL_mixer
**dans l'index correspondant à leur valeur dans l'énumération.
**retourne le nombre de fichiers son chargé.*/
int GestSons_Load(Container *sounds_list) {
	int sonsCharges = (int)(Count);
	Mix_Chunk *chunck_to_add;

	while(Container_Size(*sounds_list) <= sonsCharges) {
		Container_PushUp(sounds_list, NULL);
	}

	chunck_to_add = Mix_LoadWAV("sons/ding.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son ding.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(DING));

	chunck_to_add = Mix_LoadWAV("sons/croix.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son croix.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(CROIX));

	chunck_to_add = Mix_LoadWAV("sons/pas.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son pas.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(PAS));

	chunck_to_add = Mix_LoadWAV("sons/perdu.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son perdu.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(PERDU));

	chunck_to_add = Mix_LoadWAV("sons/gagne.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son gagne.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(GAGNE));

	chunck_to_add = Mix_LoadWAV("sons/bravo.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son bravo.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(BRAVO));

	chunck_to_add = Mix_LoadWAV("sons/viegagnee.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son viegagnee.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(VIEGAGNEE));

	chunck_to_add = Mix_LoadWAV("sons/vieperdue.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son vieperdue.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(VIEPERDUE));

	chunck_to_add = Mix_LoadWAV("sons/mange.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son mange.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(MANGE));

	chunck_to_add = Mix_LoadWAV("sons/tetris_lignePleine.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son tetris_lignePleine.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(TETRISLIGNEPLEINE));

	chunck_to_add = Mix_LoadWAV("sons/tetris_eclair.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son tetris_eclair.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(TETRISECLAIR));

	chunck_to_add = Mix_LoadWAV("sons/tetris_enBas.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son tetris_enBas.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(TETRISENBAS));

	chunck_to_add = Mix_LoadWAV("sons/tetris_newLevel.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son tetris_newLevel.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(TETRISNEWLEVEL));

	chunck_to_add = Mix_LoadWAV("sons/tetris_tourner.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son tetris_tourner.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(TETRISTOURNER));

	chunck_to_add = Mix_LoadWAV("sons/pong_balle_perdue.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son pong_balle_perdue.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(PONGBALLEPERDUE));

	chunck_to_add = Mix_LoadWAV("sons/pong_raquette.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son pong_raquette.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(PONGRAQUETTE));

	chunck_to_add = Mix_LoadWAV("sons/pong_cote.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son pong_cote.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(PONGCOTE));

	chunck_to_add = Mix_LoadWAV("sons/tower_boom.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son tower_boom.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(TOWERBOOM));

	chunck_to_add = Mix_LoadWAV("sons/tower_cote.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son tower_cote.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(TOWERCOTE));

	chunck_to_add = Mix_LoadWAV("sons/tower_transition.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son tower_transition.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(TOWERTRANSITION));

	chunck_to_add = Mix_LoadWAV("sons/tower_descendre.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son tower_descendre.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(TOWERDESCENDRE));

	chunck_to_add = Mix_LoadWAV("sons/tower_poser.wav");

	if(chunck_to_add == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger le son tower_poser.wav");
		sonsCharges--;
	}

	Container_Set(sounds_list, chunck_to_add, (int)(TOWERPOSER));

	return sonsCharges;
}

/*fonction utilisé par le thread
**permet de charger les musiques. Ils sont stockés par SDL_mixer
**dans l'index correspondant à leur valeur dans l'énumération.
**retourne le nombre de fichiers son chargé.*/
int Gestmusics_Load(Container *playList) {
	intern_playlist_node *tempNode = NULL;
	Mix_Music *tempStream = NULL;
	tempStream = Mix_LoadMUS("sons/Credits.ogg");

	if(tempStream == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger la musique Credits.ogg");
	}
	else {
		tempNode = malloc(sizeof(intern_playlist_node));
		tempNode->music = tempStream;
		tempNode->enumValue = (int)(CREDITS);
		Container_PushBack(playList, tempNode);
	}

	tempStream = Mix_LoadMUS("sons/tetris_musique.mp3");

	if(tempStream == NULL) {
		Log(LOG_SDL_mixer, "Impossible de charger la musique tetris_musique.mp3");
	}
	else {
		tempNode = malloc(sizeof(intern_playlist_node));
		tempNode->music = tempStream;
		tempNode->enumValue = (int)(TETRIS);
		Container_PushBack(playList, tempNode);
	}

	return Container_Size(*playList);
}

/* Permet de jouer la musique en tête de file
** \param music          la liste des musiques à jouer
** \param internPlayList la liste des musiques chargées par défaut
** \param curMusic       la musique en train d'être lue.
*/
void GestSons_play_music(File **music, Container internPlayList, Mix_Music *curMusic) {
	int indexMusicAJouer, i, play_return;
	bool trouvee;

	if(!File_Empty(**music)) {
		if(File_Front(**music, &indexMusicAJouer) != 0) {
			Log(LOG_DEFAULT, "GestSons_play_music : Impossible de lire la file music");
		}
		else {
			File_Pop(*music);

			if(indexMusicAJouer >= (int)(CountM) || indexMusicAJouer < 0) {
				Log(LOG_DEFAULT, "GestSons_play_music : Index de music reçus non valide");
			}
			else {
				trouvee = false;
				i = 0;

				while(i < Container_Size(internPlayList) && !trouvee) {
					if(((intern_playlist_node *)(Container_Get(internPlayList, i)))->enumValue == indexMusicAJouer) {
						trouvee = true;
					}
					else {
						i++;
					}
				}

				if(!trouvee) {
					Log(LOG_DEFAULT, "GestSons_play_music : La musique demandée n'est pas chargée.");
				}
				else {
					while(!Mix_FadeOutMusic(1500) && Mix_PlayingMusic()) {
						SDL_Delay(100);
					}
					play_return = Mix_FadeInMusic(((intern_playlist_node *)(Container_Get(internPlayList, i)))->music, 0, 500);

					if(play_return == -1) {
						Log(LOG_SDL_mixer, "La musique demandée n'a pas pu être jouée.");
						Mix_FadeInMusic(curMusic, 1, 500);
					}
				}
			}
		}
	}
}

void GestSons_jouer_son(File **son, Container sounds_list) {
	int indexSonAJouer;
	Mix_Chunk *sonAJouer;

	if(!File_Empty(**son)) {
		if(File_Front(**son, &indexSonAJouer) != 0) {
			Log(LOG_DEFAULT, "GestSons_PlaySound : Impossible de lire la file son");
		}
		else {
			File_Pop(*son);

			if((Sons)(indexSonAJouer) >= Count || indexSonAJouer < 0) {
				Log(LOG_DEFAULT, "GestSons_PlaySound : Index de son reçus non valide.");
			}
			else {
				sonAJouer = Container_Get(sounds_list, indexSonAJouer);

				if(sonAJouer == NULL) {
					Log(LOG_SDL_mixer, "Impossible de récupérer un son depuis son index.");
				}
				else {
					if(volume_son != 0) {
						if(Mix_PlayChannel(-1, sonAJouer, 0) == -1) {
							Log(LOG_SDL_mixer, "Impossible de jouer un son.");
						}
					}
				}
			}
		}
	} /*fin du traitement de la file des sons à jouer*/
}

/*fonction thread pour la gestion du son.*/
/*récupère en paramètre un pointeur sur une instance de thread_son_vars*/
void thread_gest_son(void *data) {
	int i;
	File *son;
	File *music;
	musics last_intern_music = CountM;
	Container playList = EMPTY_CONTAINER;
	Container internPlayList = EMPTY_CONTAINER;
	Container sounds_list = EMPTY_CONTAINER;
	int indexCurMusic = -1;
	Mix_Music *curMusic = NULL;
	thread_son_vars *donnees = (thread_son_vars *)(data);

	son = & (donnees->son);
	music = & (donnees->music);
	donnees->running = true;
	/*initialisation de SDL_Mixer*/

	if(SDL_Init(SDL_INIT_AUDIO) != 0) {
		Log(LOG_SDL_mixer, "Impossible d'initialiser la SDL.");
		donnees->quitter = true;
		donnees->running = false;
		return;
	}
	else if(Mix_OpenAudio(FREQ, MIX_DEFAULT_FORMAT, 2, CHUNCKSIZE) != 0) {
		Log(LOG_SDL_mixer, "Impossible d'initialiser SDL_mixer.");
		SDL_Quit();
		donnees->quitter = true;
		donnees->running = false;
		return;
	}

	/*chargement des sons*/
	if(GestSons_Load(&sounds_list) == 0) {
		Log(LOG_DEFAULT, "threadGestSon : Aucun son n'a pu être chargé.");
	}

	/*chargement des musiques*/
	if(Gestmusics_Load(&internPlayList) == 0) {
		Log(LOG_DEFAULT, "threadGestMusic : Aucune musique n'a pu être chargé.");
	}

	/*chargement de la liste de lecture*/
	GestSons_ParsePlayList(&playList);

	/*lecture de la première musique*/
	if(Container_Size(playList) != 0 && !donnees->stop) {
		GestSons_PlayNextMusic(&playList, &indexCurMusic, &curMusic, donnees->shuffle);
	}

	if(indexCurMusic == -1) {
		Log(LOG_DEFAULT, "threadGestSon : Aucune musique n'a pu être chargée et/ou lue.");
	}

	/*boucle principale*/
	while(!donnees->quitter) {
		GestSons_jouer_son(&son, sounds_list);

		if(donnees->stop) {
			if(Mix_PlayingMusic()) {
				while(!Mix_FadeOutMusic(1500) && Mix_PlayingMusic()) {
					SDL_Delay(100);
				}
			}

			if(!File_Empty(*music)) {
				File_Clear(music);
			}
		}
		else {
			if(!File_Empty(*music)) {
				File_Front(*music, (int *)(&last_intern_music));
			}

			GestSons_play_music(&music, internPlayList, curMusic);

			if(!Mix_PlayingMusic()) {
				if(donnees->loop) {
					if(last_intern_music != CountM) {
						File_Push(music, last_intern_music);
					}
					else if(curMusic != NULL) {
						if(Mix_PlayMusic(curMusic, 1) == -1) {
							Log(LOG_SDL_mixer, "thread_gest_son : le bouclage de la musique a échoué");
							donnees->loop = false;
						}
					}
				}
				else if(indexCurMusic != -1) {
					GestSons_PlayNextMusic(&playList, &indexCurMusic, &curMusic, donnees->shuffle);
					last_intern_music = CountM;
				}
			}
			else if(donnees->is_music_paused == true && !Mix_PausedMusic()) {
				Mix_PauseMusic();
			}
			else if(donnees->is_music_paused == false && Mix_PausedMusic()) {
				Mix_ResumeMusic();
			}
		} /* !donnees->stop */

		if(donnees->next == true) {
			while(!Mix_FadeOutMusic(1500) && Mix_PlayingMusic()) {
				SDL_Delay(100);
			}
			donnees->next = false;
		}

		Mix_VolumeMusic(volume_musique);
		Mix_Volume(0, volume_son);

		CSLP_Sleep(55);
	}

	for(i = 0; i < Container_Size(playList); i++) {
		if(Container_Get(playList, i) != NULL) {
			free(Container_Get(playList, i));
		}
	}

	Container_Clear(&playList);

	for(i = 0; i < Container_Size(internPlayList); i++) {
		if(Container_Get(internPlayList, i) != NULL) {
			if(((intern_playlist_node *)(Container_Get(internPlayList, i)))->music != NULL) {
				Mix_FreeMusic(((intern_playlist_node *)(Container_Get(internPlayList, i)))->music);
			}

			free(Container_Get(internPlayList, i));
		}
	}

	Container_Clear(&internPlayList);

	for(i = 0; i < Container_Size(sounds_list); i++) {
		if(Container_Get(sounds_list, i) != NULL) {
			Mix_FreeChunk((Mix_Chunk *)(Container_Get(sounds_list, i)));
		}
	}

	Container_Clear(&sounds_list);

	if(curMusic != NULL) {
		Mix_FreeMusic(curMusic);
	}

	Mix_CloseAudio();
	SDL_Quit();
	donnees->running = false;
}
